import java.util.TreeMap;
import java.util.ArrayList;
import java.util.ListIterator;

public class MultistrokeMarkingMenu {
	
	private ArrayList<MenuItem> menuItems;
	
	private final int MAX_MENU_ITEMS = 8;
	
	private double menuItemDistance;
	
	private int menuDepth;
	
	public MultistrokeMarkingMenu(MultistrokeMarkingMenu parentMenu) {
		menuItems = new ArrayList<MenuItem>();
		menuItemDistance = 100;
		if (parentMenu != null) {
			menuDepth = parentMenu.getDepth() + 1;
		} else {
			menuDepth = 1;
		}
	}
	
	public int getDepth() {
		return menuDepth;
	}
	
	public boolean addMenuItem(String name) {
		for (int i = 0; i < menuItems.size(); i++) {
			if (menuItems.get(i).getName().equalsIgnoreCase(name)) {
				System.out.println("Cannot insert duplicate menuItem names");
				return false;
			}
		}
		
		try {
			menuItems.add(new MenuItem(name, this));
			getMenuItem(name).setMenuIndexNumber(menuItems.size());
			
			MultistrokeMarkingMenu menuItemSubMenu = new MultistrokeMarkingMenu(this);
			this.setMenuItemSubMenu(name, menuItemSubMenu);
			
			
			getMenuItem(name).setCoordinate(getMenuItemCoordinate(menuItems.size()));
			return true;
		} catch(Exception e) {
			return false;
		}
	}
	
	private MenuItem getMenuItem(String name) {
		for (int i = 0; i < menuItems.size(); i++) {
			if (name.equals(menuItems.get(i).getName())) {
				return menuItems.get(i);
			}
		}
		System.err.println("Could find item: " + name);
		return null;
		
	}
	
	public boolean setMenuItemDistance(double distance) {
		try {
			this.menuItemDistance = distance;
			for (int i = 0; i < menuItems.size(); i++) {
				menuItems.get(i).setCoordinate(getMenuItemCoordinate(i + 1));
			}
			
			
			
			
			
			
			return true;
		} catch (Exception e) {
			System.err.println("Could not set menu item distance.");
			return false;
		}
	}
	
	public boolean removeMenuItem(String name) {
		try {
			MenuItem deleted = menuItems.remove(this.getMenuItem(name).getMenuIndexNumber() - 1);
			return this.syncMenuIndexNumbers() && (deleted != null);
		} catch (Exception e) {
			System.err.println("Could not remove menu item");
			return false;
		}
	}
	
	private boolean syncMenuIndexNumbers() {
		for (int i = 0; i < menuItems.size(); i++) {
			if (menuItems.get(i).setCoordinate(getMenuItemCoordinate(i + 1)) == false
					|| menuItems.get(i).setMenuIndexNumber(i + 1) == false) {
				return false;
			}
		}
		return true;
	}
	
  
	/*
     * 
     */
	private double[] getMenuItemCoordinate(int numMenuItems) {
		
		if (numMenuItems == 0 || numMenuItems > MAX_MENU_ITEMS) {
			double[] error = new double[2];
			System.err.println("Error: Number of menu items illegal.");
			return error;
		}
		
		double[] itemCoordinates = new double[2];
    
		if (numMenuItems == 1) {
			itemCoordinates[0] = 0; 
			itemCoordinates[1] = menuItemDistance;
			return itemCoordinates;
		} 
		if (numMenuItems == 2) {
			itemCoordinates[0] = 0; 
			itemCoordinates[1] = -(menuItemDistance);
			return itemCoordinates;
		} 
		if (numMenuItems == 3) {
			itemCoordinates[0] = menuItemDistance; 
			itemCoordinates[1] = 0;      
			return itemCoordinates;
		}
		if (numMenuItems == 4) {    
			itemCoordinates[0] = -(menuItemDistance); 
			itemCoordinates[1] = 0;      
			return itemCoordinates;
		}
		if (numMenuItems == 5) {  
			itemCoordinates[0] = menuItemDistance / Math.sqrt(2); 
			itemCoordinates[1] = menuItemDistance / Math.sqrt(2); 
			return itemCoordinates;
		} 
		if (numMenuItems == 6) {  
			itemCoordinates[0] = -(menuItemDistance) / Math.sqrt(2); 
			itemCoordinates[1] = -(menuItemDistance) / Math.sqrt(2);  
			return itemCoordinates;
		}
		if (numMenuItems == 7) {
			itemCoordinates[0] = -(menuItemDistance) / Math.sqrt(2); 
			itemCoordinates[1] = menuItemDistance / Math.sqrt(2);
			return itemCoordinates;
		} 
		if (numMenuItems == 8) {
			itemCoordinates[0] = menuItemDistance / Math.sqrt(2); 
			itemCoordinates[1] = -(menuItemDistance) / Math.sqrt(2);
			return itemCoordinates;
		} 
		return itemCoordinates;
	}
  
	/*
   * 
   */
	private double calculateAngle(int x1, int y1, int x2, int y2) { 
		return Math.toDegrees(Math.atan2(y2 - y1, x2 - x1));
	}
	
	public boolean setMenuItemLink(String menuItemName, String link) {
		try {
			getMenuItem(menuItemName).setLink(link);
		} catch (Exception e) {
			System.err.println("Error setting link");
			return false;
		}
		return true;
	}
	
	public boolean setMenuItemSubMenu(String menuItemName, MultistrokeMarkingMenu subMenu) {
		try {
			getMenuItem(menuItemName).setSubMenu(subMenu);
		} catch (Exception e) {
			System.err.println("Error setting submenu");
			return false;
		}
		return true;
	}
	
	public MultistrokeMarkingMenu getMenuItemSubMenu(String menuItemName) {
		if (getMenuItem(menuItemName).getSubMenu() == null) {
			return null;
		} else {
			return getMenuItem(menuItemName).getSubMenu();
		}
	}
	
	public boolean addMenuItemWithEmptySubMenu(String title) {
		try {
			MultistrokeMarkingMenu menuItemSubMenu = new MultistrokeMarkingMenu(this);
			this.addMenuItem(title);
			this.setMenuItemSubMenu(title, menuItemSubMenu);
		} catch (Exception e) {
			System.err.print("Could not create an Item Menu with Empty SubMenu");
			return false;
		}
		return true;
	}

	public String toString() {
		String output = "";
		for (int i = 0; i < menuItems.size(); i++) {
			output += menuItems.get(i);
			//System.out.print(menuItems.get(i).toXML());
		}
		return output;
	}
	
	
	public ListIterator getIterator () {
		return menuItems.listIterator();
	}
	
	
}